-module(jack_priority_queue).
-export([new/0, add/2, remove_smallest/1, get_size/1]).

-record
(
        sequence_queue,
        {
                ordered_set = gb_sets:new(), 
                dictionary = dict:new()
        }
).

new() ->
        #sequence_queue{}.
        
add(Sequence, State) ->
        OrderedSet = State#sequence_queue.ordered_set,
        Dictionary = State#sequence_queue.dictionary,
	Length = length(Sequence),
        NewOrderedSet = gb_sets:add(Length, OrderedSet),
        NewDictionary = dict:append(Length, Sequence, Dictionary),
	State#sequence_queue
	{
	        ordered_set = NewOrderedSet,
	        dictionary = NewDictionary
	}.

remove_smallest(State)
        when State#sequence_queue.ordered_set == [] ->
                State;
                 
remove_smallest(State) ->
        OrderedSet = State#sequence_queue.ordered_set,
        Dictionary = State#sequence_queue.dictionary,
	{Smallest, NewOrderedSet} = gb_sets:take_smallest(OrderedSet),
	SequenceList = dict:fetch(Smallest, Dictionary),
	[_HeadSequence, NewSequenceList] = SequenceList,
	case NewSequenceList of
	        [] ->
	                NewDictionary = dict:delete(Smallest, Dictionary),
	                State#sequence_queue
	                {
	                        ordered_set = NewOrderedSet,
	                        dictionary = NewDictionary
	                };
	        _ ->
	                NewDictionary = dict:store(NewSequenceList, Dictionary),
	                State#sequence_queue
	                {
	                        dictionary = NewDictionary
	                }	                
	end.

get_size(State) ->
        Dictionary = State#sequence_queue.dictionary,
        dict:size(Dictionary).
